#pragma once
#ifndef _D3D_TYPES_H
#define _D3D_TYPES_H

#include <d3dx9.h>
#include "interface_types.h"

#include "..\math\math.h"
#include "..\math\plane.h"
#include "..\common\def.h"
#include "..\common\string.h"
class CD3D9Device; 
struct Texture;
struct D3DShader;
struct D3DImage;
struct Color3f;

/**************************************
 * General utility functions
 **************************************/
D3DXVECTOR3 VectorToD3DVector3(const Vector3f& vec);
D3DXVECTOR4 VectorToD3DVector4(const Vector3f& vec);
Vector3f D3DVector3ToVector(const D3DXVECTOR3& vec);
D3DXVECTOR3 ColorToD3DVector3(const Color3f& col);
D3DXVECTOR4 ColorToD3DVector4(const Color3f& col);
DWORD ColorToD3DColor(const Color3f& col);
D3DXMATRIX GetProjectionTransform(float Near, float Far, float fov, float aspect);
void GetVertexCloudMetrics(VertexComplex* pVertices, unsigned int vertexCount, Vector3f* pCenter, float* pRadius);


/**************************************
 * Resource interface inherited by all 
 * rendering resources
 **************************************/
struct EE_EXPORT IResource
{
private:
	CD3D9Device* m_pD3DDevice; 

protected:
	IResource(CD3D9Device* const pDevice); 
	CD3D9Device* GetDevice() const; 
	string	m_Identity; 
	bool	m_IsValid; 
public:
	string Identity(); 
	bool IsValid(); 
	virtual string GetType() const = 0; 
	virtual HRESULT Reload() = 0; 
	virtual HRESULT Release() = 0; 
}; 

/**************************************
 * An abstraction layer for common 
 * renderable objects
 **************************************/
struct EE_EXPORT D3DRenderable : public IResource
{
protected:
	
	//For acess to data for bound checking during loadtime
	friend class D3DModel;

	Vector3f m_Velocity;
	int m_RenderFlags;
	unsigned int m_NumPrimitives; 
	Texture* m_pTextureUnitA; 
	VertexComplex *m_pVertices;
	unsigned short *m_pIndicies; 
	D3DShader *m_pShader; 
	float m_Radius;
	bool m_IsInstance;

public:
	//TODO:privatize
	LPDIRECT3DINDEXBUFFER9 pIndexBuffer; 
	LPDIRECT3DVERTEXBUFFER9 pVertexBuffer; 
	unsigned int m_ElementSize;
//	LPDIRECT3DVERTEXDECLARATION9 m_pVertexDeclaration;

	D3DRenderable(CD3D9Device* const pDevice);

	void setRenderFlags(const unsigned int flags);
	void setShader(D3DShader* pShader); 
	void setVelocity(const Vector3f& velocity); 
	virtual void setTexture(Texture* pTexture, const unsigned int unit) = 0; 
	virtual Texture* getTexture(const unsigned int idx) = 0;
	virtual Texture* getMaskTexture();
	virtual Vector3f getVelocity() const;
	float GetRadius() const;
	D3DShader* getShader();

	unsigned int getRenderFlags() const;
	virtual unsigned int getVertexCount() const;
	virtual void* getVertices();
	virtual unsigned short* getIndicies();
	virtual void Draw(const Matrix4f &transform, D3DShader* const pShader); 
	virtual HRESULT PreRender();
	virtual void Render(const unsigned int offset) = 0;
	virtual HRESULT PostRender();
};

/**************************************
 * Stores buffers and surfaces for 
 * rendering data and results
 **************************************/
struct RenderTarget : public IResource
{
public:
	RenderTarget(CD3D9Device* const pDevice); 

	HRESULT Release(); 
	HRESULT Reload(); 

	string GetType() const; 
	D3DCOLOR				m_ClearColor; 
	DWORD					m_ClearFlags; 
	LPD3DXRENDERTOSURFACE	m_pTargetSurface; 
	LPDIRECT3DSURFACE9		m_pSurface; 
	LPDIRECT3DTEXTURE9		m_pTargetTexture; 
}; 

/**************************************
 * Stores view orrientation data for
 * cameras and directional lights
 **************************************/
struct EE_EXPORT ViewOrrientation
{
public:
	enum EE_EXPORT FrustrmSides{ NEAR_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, TOP_PLANE, FAR_PLANE }; 
		
	ViewOrrientation();
	
	D3DXMATRIX				m_View; 
	Vector3f				m_Position; 
	D3DXMATRIX				m_Projection; 
	Planef					m_frustrumPlanes[6]; 

	inline static bool ContainsSphere(ViewOrrientation* view, Spheref* pBoundsSphere);
	inline static bool ContainsPoints(ViewOrrientation* view,Vector3f* pPoints, uint count);
	inline static bool ContainsPoint(ViewOrrientation* view,const Vector3f& point);

}; 

/**************************************
 * Stores font data and buffers text for
 * displaying on screen text
 **************************************/
class ScreenText : public IResource
{				
public:
	enum TextFace { DEFAULT_FACE = 0, BOLD_FACE = 1, ERROR_FACE = 2 }; 
	static const int NUM_TEXT_LINES; 
	static const int NUM_CHARS_LINE; 
	static const int TEXT_FONT_HEIGHT; 
	static const int LINE_SPACING; 
	static const float TEXT_CLEAR_TIMER; 

	LPD3DXFONT	m_pFontDefault; 
	LPD3DXFONT	m_pFontBold; 
	string	*m_pLines; 
	DWORD	*m_pFlags; 
	int		m_OnLine; 
	float	m_ClearTimer; 

	ScreenText(CD3D9Device* const pDevice); 
	virtual ~ScreenText(); 

	string GetType() const; 
	HRESULT Release(); 
	HRESULT Reload(); 
}; 

struct D3DShader; 

/**************************************
 * Stores data for transfering mesh information
 * TODO: is redundant?
 **************************************/
struct EE_EXPORT MeshPartData
{
	MeshPartData(); 

	D3DShader *m_pShader; 
	VertexComplex *m_pVertices; 
	unsigned short *m_pIndicies; 
	unsigned int vertexCount; 
	unsigned int triangleCount; 
	unsigned int frameCount; 
	float opacity;

	string diffuseMap; 
	string bumpMap; 
	string specularMap; 
	string opacityMap; 
	string giMap; 
	string shaderFilename; 
}; 		

/**************************************
 * Stores data for fog effects
 **************************************/
struct EE_EXPORT FogData
{
	FogData(); 

	float m_Start;
	float m_End;
	D3DXVECTOR4 m_StartColor;
	D3DXVECTOR4 m_EndColor;
	D3DXVECTOR3 m_FogPlane;
}; 		

/**************************************
 * Stores data for sun effects
 **************************************/
struct EE_EXPORT SunData
{
	SunData(); 
	HRESULT CreateFlares(const string& flare,const string& haloA,const string& haloB,const string& haloC);
	HRESULT ReleaseFlares();
	
	D3DImage* m_pFlares[4];

	D3DXVECTOR3 m_Position;
	D3DXVECTOR3 m_Direction;
	D3DXVECTOR3 m_Ambience;
	D3DXVECTOR3 m_Diffuse;

	bool m_IsActive;
}; 		


#endif